package cn.fintecher.gis.web;

import cn.fintecher.gis.enums.EnumMessage;
import cn.fintecher.gis.model.DataDict;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ClassUtils;
import org.springframework.util.SystemPropertyUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/dataDictController")
@Api(value = "数据字典相关", description = "数据字典相关")
public class DataDictController {

    private final static String BASE_PACKAGE = "cn.fintecher.gis.enums";

    private static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";

    private final Logger log = LoggerFactory.getLogger(DataDictController.class);

    @Autowired
    private MessageSource messageSource;

    private static Class loadClass(MetadataReaderFactory metadataReaderFactory, Resource resource) throws IOException, ClassNotFoundException {
        if (resource.isReadable()) {
            MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
            return Class.forName(metadataReader.getClassMetadata().getClassName());
//            if (aClass.getAnnotation(Dict.class) != null) {
//                return aClass;
//            }
        }
        return null;
    }

    @GetMapping("/DataDictHashCode")
    @ApiOperation(value = "获取数据字典的hashCode", notes = "获取数据字典的hashCode")
    public ResponseEntity<Map<String, String>> DataDictHashCode() {
        Map<String, String> map = new HashMap<>();
        Set<Class> list = findDictAnnotationClass();
        String code = String.valueOf(list.hashCode());
        map.put("dataDictHashCode", code);
        return ResponseEntity.ok().body(map);
    }

    @ApiOperation(value = "获取数据字典", notes = "获取数据字典")
    @GetMapping("/getAll")
    public ResponseEntity<Map<String, Collection<DataDict>>> getAll(WebRequest request) throws ClassNotFoundException {
        log.debug("获取数据字典项目 local为：{}", request.getLocale());
        Multimap<String, DataDict> dictMultimap = ArrayListMultimap.create();

//        List<Class<EnumMessage>> list = InterfaceHelp.getDataClass("cn.fintecher.pangolin.common.enums", EnumMessage.class);
        Set<Class> list = findDictAnnotationClass();
        list = list.stream().filter(Class::isEnum).collect(Collectors.toSet());

        for (Class<?> l : list) {

            Class c = Class.forName(l.getName());
            if (Objects.isNull(c.getEnumConstants())) {
                continue;
            }

            for (Object obj : c.getEnumConstants()) {
                DataDict dataDict = new DataDict(((Enum<?>) obj).name(), messageSource.getMessage(((EnumMessage) obj).getMessageKey((Enum<?>) obj), null, Locale.CHINA));
                dictMultimap.put(c.getSimpleName(), dataDict);
            }

        }
        return ResponseEntity.ok().body(dictMultimap.asMap());
    }

    private Set<Class> findDictAnnotationClass() {
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
        Set<Class> clazzSet = new HashSet<>();
        String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(BASE_PACKAGE)) + "/" + DEFAULT_RESOURCE_PATTERN;
        try {
            Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
            for (Resource resource : resources) {
                //检查resource，这里的resource都是class
                Class clazz = loadClass(metadataReaderFactory, resource);
                if (clazz != null) {
                    clazzSet.add(clazz);
                }
            }
        } catch (Exception ex) {
            log.error("加载数据字典类出现错误", ex);
        }
        return clazzSet;
    }
}
